﻿// WebZHX.Infrastructure/Extensions/ServiceCollectionExtensions.cs
using Core.Interfaces;
using Infrastructure.Repositories.Base;
using Infrastructure.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Reflection;

namespace Infrastructure.Extensions
{
    /// <summary>
    /// 服务集合扩展方法
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 添加基础设施层服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">配置</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
        {
            // 注册Dapper仓储
            services.AddScoped<IDapperRepository, DapperRepository>();

            // 自动注册所有实体对应的仓储和基础服务
            AutoRegisterEntityRepositoriesAndServices(services);

            // 自动注册所有自定义服务
            AutoRegisterCustomServices(services);

            // 注册单例服务
            services.AddSingleton<FileLoggerService>();

            return services;
        }

        /// <summary>
        /// 自动注册所有实体对应的仓储和基础服务
        /// </summary>
        private static void AutoRegisterEntityRepositoriesAndServices(IServiceCollection services)
        {
            var coreAssembly = Assembly.Load("Core");
            var entityTypes = coreAssembly.GetTypes()
                .Where(t => t.IsClass &&
                           !t.IsAbstract &&
                           t.GetInterfaces().Any(i => i.IsGenericType &&
                           i.GetGenericTypeDefinition() == typeof(IEntity<>)))
                .ToList();

            foreach (var entityType in entityTypes)
            {
                var entityInterface = entityType.GetInterfaces()
                    .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEntity<>));

                var keyType = entityInterface?.GetGenericArguments()[0] ?? typeof(int);

                // 注册仓储
                var repositoryType = typeof(EfRepository<,>).MakeGenericType(entityType, keyType);
                var interfaceType = typeof(IBaseRepository<,>).MakeGenericType(entityType, keyType);
                var pagedInterfaceType = typeof(IPagedRepository<,>).MakeGenericType(entityType, keyType);

                services.AddScoped(interfaceType, repositoryType);
                services.AddScoped(pagedInterfaceType, repositoryType);

                // 注册基础服务
                var baseServiceType = typeof(BaseService<,>).MakeGenericType(entityType, keyType);
                services.AddScoped(baseServiceType);
            }
        }

        /// <summary>
        /// 自动注册所有自定义服务
        /// </summary>
        private static void AutoRegisterCustomServices(IServiceCollection services)
        {
            // 获取当前程序集（Infrastructure）
            var infrastructureAssembly = Assembly.GetExecutingAssembly();

            // 获取所有服务类（以Service结尾的非抽象类）
            var serviceTypes = infrastructureAssembly.GetTypes()
                .Where(t => t.IsClass &&
                           !t.IsAbstract &&
                           t.Name.EndsWith("Service") &&
                           t != typeof(BaseService<,>) && // 排除基础服务
                           !t.IsGenericType) // 排除泛型类型
                .ToList();

            foreach (var serviceType in serviceTypes)
            {
                // 查找对应的接口
                var interfaceType = serviceType.GetInterfaces()
                    .FirstOrDefault(i => i.Name == $"I{serviceType.Name}");

                if (interfaceType != null)
                {
                    // 注册为接口->实现
                    services.AddScoped(interfaceType, serviceType);
                    Console.WriteLine($"已自动注册服务: {interfaceType.Name} -> {serviceType.Name}");
                }
                else
                {
                    // 如果没有接口，直接注册类
                    services.AddScoped(serviceType);
                    Console.WriteLine($"已自动注册服务: {serviceType.Name}");
                }
            }
        }
    }
}